<template>
  <el-switch
    v-model="themeMode"
    inline-prompt
    active-value="dark"
    inactive-value="light"
    :active-icon="Moon"
    :inactive-icon="Sunny"
    @click="switchColorScheme"
  />
</template>

<script setup>
import { storeToRefs } from 'pinia'
import { useTheme } from '@/hooks/useTheme'
import { useThemeStore } from '@/stores/theme'
import { Sunny, Moon } from '@element-plus/icons-vue'

const { setTheme } = useTheme()
const themeStore = useThemeStore()
const { themeMode } = storeToRefs(themeStore)

// 使用 click 以便获取原点击事件对象
function switchColorScheme(event) {
  // 获取到 transition API 实例
  const transition = document.startViewTransition(() => {
    setTheme(themeMode.value)
  })

  transition.ready.then(() => {
    const { clientX, clientY } = event

    // 计算半径，以鼠标点击的位置为圆心，到四个角的距离中最大的那个作为半径
    const radius = Math.hypot(Math.max(clientX, innerWidth - clientX), Math.max(clientY, innerHeight - clientY))
    const clipPath = [`circle(0px at ${clientX}px ${clientY}px)`, `circle(${radius}px at ${clientX}px ${clientY}px)`]

    // 自定义动画
    document.documentElement.animate(
      {
        clipPath: themeMode.value === 'dark' ? clipPath.reverse() : clipPath,
      },
      {
        duration: 600,
        fill: 'both',
        easing: 'ease-out',
        pseudoElement: themeMode.value === 'dark' ? '::view-transition-old(root)' : '::view-transition-new(root)',
      }
    )
  })
}
</script>

<style lang="scss">
/* 主题切换 view transition 特效 */
:root {
  &::view-transition-old(root),
  &::view-transition-new(root) {
    mix-blend-mode: normal;
    animation: none;
  }

  &::view-transition-old(root) {
    z-index: 1;
  }
  &::view-transition-new(root) {
    z-index: 9999;
  }

  &.dark {
    &::view-transition-old(root) {
      z-index: 9999;
    }
    &::view-transition-new(root) {
      z-index: 1;
    }
  }
}
</style>
